package soar.template.springboot.service.hello.configuration.redis;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;

import redis.clients.jedis.JedisPoolConfig;
import soar.template.springboot.service.hello.appconfig.redis.Config;
import soar.template.springboot.service.hello.appconfig.AppConfig;

@Configuration
class MyRedisConfiguration
{
    @Resource(name = "appconfig")
    private AppConfig appconfig;

    @Bean(name = "mainRedisConnectionFactory")
    public RedisConnectionFactory mainRedisConnectionFactory()
    {
        if (appconfig.redis.main.cluster == false)
            return create_factory(appconfig.redis.main);
        else
            return create_cluster_factory(appconfig.redis.main);
    }

    @Bean(name = "mainRedisTemplate")
    public StringRedisTemplate mainRedisTemplate()
    {
        StringRedisTemplate template = new StringRedisTemplate(
                mainRedisConnectionFactory());
        return template;
    }

    private RedisConnectionFactory create_factory(Config config)
    {
        JedisPoolConfig pool_config = new JedisPoolConfig();
        pool_config.setBlockWhenExhausted(false);
        pool_config.setMaxTotal(100);
        pool_config.setTestOnBorrow(true);
        pool_config.setTimeBetweenEvictionRunsMillis(10 * 1000);
        pool_config.setMinEvictableIdleTimeMillis(30 * 1000);
        JedisConnectionFactory factory = new JedisConnectionFactory(
                pool_config);
        List<String> nodes = Arrays.asList(config.nodes.split(",")).stream()
                .map(String::trim).filter(n -> !n.isEmpty())
                .collect(Collectors.toList());
        String host = "localhost";
        int port = 6397;
        if (!nodes.isEmpty())
        {
            List<String> host_port = Arrays.asList(nodes.get(0).split(":"))
                    .stream().map(String::trim).collect(Collectors.toList());
            String h = "";
            String p = "";
            if (host_port.size() == 2)
            {
                h = host_port.get(0);
                p = host_port.get(1);
            }
            else if (host_port.size() == 1)
            {
                h = host_port.get(0);
            }
            if (!h.isEmpty())
                host = h;
            if (!p.isEmpty())
                port = Integer.valueOf(p);
        }
        factory.setHostName(host);
        factory.setPort(port);
        return factory;
    }

    private RedisConnectionFactory create_cluster_factory(Config config)
    {
        JedisPoolConfig pool_config = new JedisPoolConfig();
        pool_config.setBlockWhenExhausted(false);
        pool_config.setMaxTotal(100);
        pool_config.setTestOnBorrow(true);
        pool_config.setTimeBetweenEvictionRunsMillis(10 * 1000);
        pool_config.setMinEvictableIdleTimeMillis(30 * 1000);
        RedisClusterConfiguration cluster_config = new RedisClusterConfiguration(
                Arrays.asList(config.nodes.split(",")).stream()
                        .map(String::trim).filter(n -> !n.isEmpty())
                        .collect(Collectors.toList()));
        JedisConnectionFactory factory = new JedisConnectionFactory(
                cluster_config, pool_config);
        return factory;
    }
}
